package com.kw.rabbittest.transaction.procuder;

import com.alibaba.fastjson.JSONObject;

import com.kw.rabbittest.transaction.RabbitMQConfig;
import com.kw.rabbittest.transaction.entity.SysUser;
import com.kw.rabbittest.transaction.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Component
@Slf4j
public class UserProducer implements RabbitTemplate.ConfirmCallback {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
 
 
    @Transactional
    public String send() {
        String msgId = UUID.randomUUID().toString();
        SysUser user = createUser(msgId);
        int result = sysUserMapper.addUser(user);
        if (result <= 0) {
            return msgId;
        }
        //3.使用消息中间件异步 ，分配订单
        String sendMsgJson = JSONObject.toJSONString(user);
        send(sendMsgJson);
//        int i = 1 / 0;
        return msgId;
    }
 
    public SysUser createUser(String msgId) {
        SysUser user = new SysUser();
        user.setMsgId(msgId);
        user.setName("mq分布式事务");
        return user;
    }
 
    private void send(String sendMsg) {
 
        log.info(">>>生产者发送数据:" + sendMsg);
        // 设置生产者消息确认机制
        this.rabbitTemplate.setMandatory(true);
        this.rabbitTemplate.setConfirmCallback(this);
        // 构建回调返回参数
        CorrelationData correlationData = new CorrelationData(sendMsg);
        rabbitTemplate.convertAndSend(RabbitMQConfig.playerExchange, RabbitMQConfig.playerRountingKey, sendMsg, correlationData);
    }
 
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String s) {
        String sendMsg = correlationData.getId();
        System.out.println("生产者开始消息确认:" + sendMsg);
        if (!ack) {
            // 递归调用发送
            send(sendMsg);
            return;
        }
        System.out.println("生产者消息确认:" + sendMsg);
    }
}
